package com.example.demo.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.CaseFormat;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
*
* @author liangxn
* @date 2019/12/21
*/
public class QueryWrapperHelper {

    //DCL双端捡锁机制，多线程下单例模式在99.9%情况下都正确，但还是不能保证完全正确。因为在多线程环境下，底层为了优化有指令重排。
    //加入volatile，解决1中的问题，最终达到线程安全。
    private static volatile QueryWrapperHelper instance = null;

    private QueryWrapperHelper() {
    }

    public static QueryWrapperHelper getInstance() {
        if (instance == null) {
            synchronized (QueryWrapperHelper.class) {
                if (instance == null) {
                    instance = new QueryWrapperHelper();
                }
            }
        }

        return instance;
    }

    /**
    * 实体类的属性转化为mybatis-plus的QueryWrapper，用于创建查询过滤条件
    * @param entity
    * @param queryWrapper
    * @param <T>
    * @throws NoSuchMethodException
    * @throws InvocationTargetException
    * @throws IllegalAccessException
    */
    public <T> void convert(T entity, QueryWrapper<T> queryWrapper) throws NoSuchMethodException,
        InvocationTargetException, IllegalAccessException {
        if(entity == null){
                return;
        }

        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            if ("serialVersionUID".equals(field.getName())) {
                continue;
            }

            String col = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName());
            String entityField = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, field.getName());
            Object fieldValue = null;

            fieldValue = entity.getClass().getMethod("get" + entityField, new Class[]{}).invoke(entity);
            if (ObjectUtils.isEmpty(fieldValue)) {
                continue;
            }
            queryWrapper.eq(col, fieldValue);
        }
    }
}